#include "Defs.h"
#include "Trace.h"


File_T * Trace_T::s_filePtr = 0;
CriticalSection_T Trace_T::s_cs;
Timer_T Trace_T::s_timer;


void Trace_T::Open(const char * szFilename)
{
	s_filePtr = new File_T(szFilename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_ALWAYS, true);

	//
	// Write initialization data
	//

	SYSTEMTIME currentTime;
	s_timer.GetCurrent(currentTime);

	char szBuffer[8192];
	_snprintf(szBuffer, sizeof(szBuffer) - 1, TRACE_TEMPLATE,
		currentTime.wYear,
		currentTime.wMonth,
		currentTime.wDay,
		currentTime.wHour,
		currentTime.wMinute,
		currentTime.wSecond);

	s_filePtr->Write(szBuffer);
}

void Trace_T::Close()
{
	if( s_filePtr )
	{
		delete s_filePtr;
	}
}

void Trace_T::Initialize(const char * sz)
{
	if( s_filePtr )
	{
		s_filePtr->Write(sz);
	}
}

void Trace_T::Write(const char * sz, ...)
{
	char szData[512];
	FillMemory(szData, sizeof(szData), 0);

	va_list args;
	va_start(args, sz);
	_vsnprintf(szData, sizeof(szData) - 1, sz, args);
	va_end(args);

	ODS(szData);

	if( s_filePtr )
	{
		char szWrite[512];
		FillMemory(szWrite, sizeof(szWrite), 0);

		_snprintf(szWrite, sizeof(szWrite) - 1, " [%s]\r\n", szData);

		s_cs.Enter();
		WriteDate();
		s_filePtr->Write(szWrite);
		s_cs.Leave();
	}
}

void Trace_T::Write(DWORD dwError, const char * szFile, int iLine, const char * szFunction)
{
	char szData[512];
	FillMemory(szData, sizeof(szData), 0);

	_snprintf(szData, sizeof(szData) - 1, "Error %d at %s (%d) in %s",
		dwError, 
		szFile,
		iLine,
		szFunction);

	ODS(szData);

	if( s_filePtr )
	{
		char szWrite[512];
		FillMemory(szWrite, sizeof(szWrite), 0);

		_snprintf(szWrite, sizeof(szWrite) - 1, " [%s]\r\n", szData);

		s_cs.Enter();
		WriteDate();
		s_filePtr->Write(szWrite);
		s_cs.Leave();
	}
}

void Trace_T::WriteDate()
{
	char szData[50];
	FillMemory(szData, sizeof(szData), 0);
	
	SYSTEMTIME currentTime;
	s_timer.GetCurrent(currentTime);
	
	_snprintf(szData, sizeof(szData) - 1, "[%04d-%02d-%02d] [%02d:%02d:%02d:%03d]",
		currentTime.wYear,
		currentTime.wMonth,
		currentTime.wDay,
		currentTime.wHour,
		currentTime.wMinute,
		currentTime.wSecond,
		currentTime.wMilliseconds);

	s_filePtr->Write(szData);
}